package cn.com.lsy.product.lepao.util;

import cn.com.lsy.product.lepao.common.Constant;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.text.DateFormat;
import java.text.Format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author huangke
 */
public class CommonFunctionUtil {

    /**
     * @param str 需要加密的字符串
     * @return
     */
    public static String encryptionPwd(String str) {

        return string32MD5(str);
    }

    /***
     * MD5加码 生成32位md5码
     */
    public static String string32MD5(String inStr) {
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
        } catch (Exception e) {
            System.out.println(e.toString());
            e.printStackTrace();
            return "";
        }
        char[] charArray = inStr.toCharArray();
        byte[] byteArray = new byte[charArray.length];

        for (int i = 0; i < charArray.length; i++)
            byteArray[i] = (byte) charArray[i];
        byte[] md5Bytes = md5.digest(byteArray);
        StringBuffer hexValue = new StringBuffer();
        for (int i = 0; i < md5Bytes.length; i++) {
            int val = ((int) md5Bytes[i]) & 0xff;
            if (val < 16)
                hexValue.append("0");
            hexValue.append(Integer.toHexString(val));
        }
        return hexValue.toString();

    }

    /**
     * 将date类型转为string
     *
     * @param time
     * @param formatType
     * @return
     */
    public static String changeTimeString(Date time, String formatType) {

        SimpleDateFormat formatter = new SimpleDateFormat(formatType);

        return formatter.format(time);
    }

    /**
     * 将string类型转为date
     *
     * @param time
     * @param formatType
     * @return
     */
    public static Date changeTimeDate(String time, String formatType) throws ParseException {

        SimpleDateFormat formatter = new SimpleDateFormat(formatType);

        return formatter.parse(time);
    }

    /**
     * 获取当前时间，返回string类型
     *
     * @param formatType
     * @return
     * @throws ParseException
     */
    public static String getStringTime(String formatType) {

        SimpleDateFormat formatter = new SimpleDateFormat(formatType);

        return formatter.format(new Date());
    }

    /**
     * 获取当前时间，返回date类型
     *
     * @param formatType
     * @return
     * @throws ParseException
     */
    public static Date getDateTime(String formatType) throws ParseException {

        SimpleDateFormat formatter = new SimpleDateFormat(formatType);

        return formatter.parse(formatter.format(new Date()));
    }

    /**
     * 生成uuid
     *
     * @return
     */
    public static String createUuid() {

        return UUID.randomUUID().toString().replace("-", "").toLowerCase();
    }

    /**
     * 随机验证码
     *
     * @return
     */
    public static String random() {

        int result = (int) ((Math.random() * 9 + 1) * 100000);

        return String.valueOf(result);
    }

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url   发送请求的 URL
     * @param param 请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param, Map<String, String> header) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

            //设置请求头
            for (Map.Entry<String, String> value : header.entrySet()) {
                conn.setRequestProperty(value.getKey(), value.getValue());
            }

            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

    /**
     * @Description: 获取客户端IP地址
     */
    public static String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            if (ip.equals("127.0.0.1")) {
                // 根据网卡取本机配置的IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                ip = inet.getHostAddress();
            }
        }
        // 多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (ip != null && ip.length() > 15) {
            if (ip.indexOf(",") > 0) {
                ip = ip.substring(0, ip.indexOf(","));
            }
        }
        return ip;
    }


    /**
     * 求[Min,Max]区间之间的随机整数。
     *
     * @param Min 最小值
     * @param Max 最大值
     * @return 一个Min和Max之间的随机整数
     */
    public static int randomIntMinToMax(int Min, int Max) {
        //如果相等，直接返回，还生成个屁
        if (Min == Max) {
            return Max;
        }
        //如果Min比Max大，交换两个的值，如果不交换下面nextInt()会出错
        if (Min > Max) {
            Min ^= Max;
            Max ^= Min;
            Min ^= Max;
        }
        Random rand = new Random();//nextInt()不是静态方法，不能直接用类名调用
        return rand.nextInt(Max - Min + 1) + Min;
    }


    /**
     * 获取某个日期N天前或者N天后的日期
     *
     * @param day  天数，正数获取N天后，负数获取N天前
     * @param date 日期
     * @return
     */
    public static String getDateNextTime(int day, Date date, String formatType) {

        SimpleDateFormat sdf = new SimpleDateFormat(formatType);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // add方法中的第二个参数n中，正数表示该日期后n天，负数表示该日期的前n天
        calendar.add(Calendar.DATE, day);
        Date date1 = calendar.getTime();
        String out = sdf.format(date1);

        return out;
    }


    /**
     * 获取两个日期之间的所有日期
     *
     * @param startTime 开始日期
     * @param endTime   结束日期
     * @return
     */
    public static List<String> getDays(String startTime, String endTime, String formatType) {

        // 返回的日期集合
        List<String> days = new ArrayList<String>();

        DateFormat dateFormat = new SimpleDateFormat(formatType);
        try {
            Date start = dateFormat.parse(startTime);
            Date end = dateFormat.parse(endTime);

            Calendar tempStart = Calendar.getInstance();
            tempStart.setTime(start);

            Calendar tempEnd = Calendar.getInstance();
            tempEnd.setTime(end);
            tempEnd.add(Calendar.DATE, +1);// 日期加1(包含结束)
            while (tempStart.before(tempEnd)) {
                days.add(dateFormat.format(tempStart.getTime()));
                tempStart.add(Calendar.DAY_OF_YEAR, 1);
            }

        } catch (ParseException e) {
            e.printStackTrace();
        }

        return days;
    }


    /**
     * 获取当前日期是星期几<br>
     *
     * @param
     * @return 当前日期是星期几
     */
    public static String getWeekOfDate(String time) {

        Date date = new Date();
        try {
            date = CommonFunctionUtil.changeTimeDate(time, Constant.formatType.date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        String[] weekDays = {"日", "一", "二", "三", "四", "五", "六"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;
        return weekDays[w];
    }


    /**
     * 从list中随机抽取元素
     *
     * @param list
     * @param
     * @return void
     * @throws
     * @Title: createRandomList
     * @Description: TODO
     */
    public static List createRandomList(List list, int n) {
        // TODO Auto-generated method stub
        Map map = new HashMap();
        List listNew = new ArrayList();
        if (list.size() <= n) {
            return list;
        } else {
            while (map.size() < n) {
                int random = (int) (Math.random() * list.size());
                if (!map.containsKey(random)) {
                    map.put(random, "");
                    listNew.add(list.get(random));
                }
            }
            return listNew;
        }
    }


    /***
     * 获取两个日期相差的天数
     * @param time
     * @return
     */
    public static long CalculateTime(String time) {

        long nowTime = System.currentTimeMillis(); // 获取当前时间的毫秒数
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 指定时间格式
        Date setTime = null; // 指定时间
        try {
            setTime = sdf.parse(time); // 将字符串转换为指定的时间格式
        } catch (ParseException e) {

            e.printStackTrace();
        }
        long reset = setTime.getTime(); // 获取指定时间的毫秒数
        long dateDiff = nowTime - reset;

        long second = dateDiff / 1000; // 秒
        long minute = second / 60; // 分钟
        long hour = minute / 60; // 小时
        long day = Math.abs(hour / 24); // 天数
        if (day <= 0) {
            day = 1;
        }
        return day;
    }


    /***
     * 当前日期和指定日期相差的天数
     * @param time
     * @return
     */
    public static long calculateTime(Date time) {
        //开始时间
        Date startDate = new Date();
        //得到相差的天数 betweenDate
        long betweenDate = (time.getTime() - startDate.getTime()) / (60 * 60 * 24 * 1000);

        return betweenDate;
    }


    /**
     * 转换支付方式
     *
     * @param type
     * @return
     */
    public static String getPayType(String type) {

        String result = "";

        if (type.equals(Constant.getPayType.aliPay)) {
            result = "支付宝支付";
        } else if (type.equals(Constant.getPayType.weChatPay)) {
            result = "微信支付";
        } else if (type.equals(Constant.getPayType.balancePay)) {
            result = "余额支付";
        }

        return result;
    }


    /**
     * 转换优惠方式
     *
     * @param type
     * @return
     */
    public static String getDiscountType(String type) {

        String result = "";

        if (type.equals(Constant.discountType.coupon)) {
            result = "优惠劵";
        }

        return result;
    }


    /**
     * 转换用户来源
     *
     * @param type
     * @return
     */
    public static String getUserSource(String type) {

        String result = "";

        if (type.equals(Constant.userSource.register)) {
            result = "自流量";
        } else if (type.equals(Constant.userSource.recommend)) {
            result = "好友推荐";
        }

        return result;
    }


    /**
     * 转换消息类型
     *
     * @param type
     * @return
     */
    public static String getMessageType(String type) {

        String result = "";

        if (type.equals(Constant.messageType.system)) {
            result = "系统消息";
        } else if (type.equals(Constant.messageType.user)) {
            result = "个人消息";
        }

        return result;
    }


    /**
     * 返回指定时间之后day天的时间（结束日期的凌晨三点）
     *
     * @param day
     * @param initTime
     * @return
     */
    public static Date getTimeToAfter(int day, Date initTime) {
        SimpleDateFormat sdf = new SimpleDateFormat(Constant.formatType.date);
        Format format = new SimpleDateFormat(Constant.formatType.date);
        long time = 0;
        Date today = null;
        try {
            String secondTime = changeTimeString(initTime, Constant.formatType.date);
            today = sdf.parse(secondTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //日期截止为凌晨三点 所以 * 27
        time = (today.getTime() / 1000) + 60 * 60 * (day * 24 + 3);
        Date newDate = new Date();
        newDate.setTime(time * 1000);
        return newDate;
    }

    //获取本月最后一天的方法
    public static String getMonthLastDay() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime());
    }


    /**
     * 计算两个日期相差的天数
     *
     * @param startTime ： 开始时间
     * @param endTime   ： 结束时间
     * @return
     */
    public static int caculateTotalTime(String startTime, String endTime) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Date date1 = null;
        Date date = null;
        Long l = 0L;
        try {
            date = formatter.parse(startTime);
            long ts = date.getTime();
            date1 = formatter.parse(endTime);
            long ts1 = date1.getTime();

            l = (ts - ts1) / (1000 * 60 * 60 * 24);

        } catch (ParseException e) {
            e.printStackTrace();
        }
        return l.intValue();
    }


    /**
     * 获取某月的最后一天
     */
    public static String getLastDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份
        cal.set(Calendar.MONTH, month - 1);
        //获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        //设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        //格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String lastDayOfMonth = sdf.format(cal.getTime());

        return lastDayOfMonth;
    }
}
